package edu.rpi.tw.impav;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;

import com.hp.hpl.jena.ontology.Individual;


public class GraphBuilder implements Runnable {

    private TweetQueue queue;
    
    private Graph graph;
    
    private App app;
    
    private boolean run = true;
    
    public synchronized void pleaseStop() {
        run = false;
    }
    
    public GraphBuilder(TweetQueue queue, Graph graph, App app) {
        this.queue = queue;
        this.graph = graph;
        this.app = app;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                if (!run) return;
            }
            List<Tweet> tweets = new LinkedList<Tweet>();
            BlockingQueue<Tweet> q = queue.getTweets();
            
            // First attempt to get a single tweet, 
            // blocking until there is at least one.
            try {
                Tweet t = q.take();
                tweets.add(t);
            } catch (InterruptedException e) {
            }
            // Once we've established that there's at least one,
            // drain the rest to the list for processing.
            q.drainTo(tweets);
            
            // Build up the graph nodes.
            synchronized(app) {
                processTweets(tweets);
                graph.runExpiration();
            }
            
        }
    }

    private void processTweets(List<Tweet> tweets) {
        for (Tweet t : tweets) {
            List<Node> nodes = new ArrayList<Node>();
            graph.seedPosition(t.termVector);
            for (Individual i: t.termVector) {
                Node node = graph.getNode(i);
                synchronized(node) {
                    synchronized(nodes) {
                        node.addTweet(t);
                        nodes.add(node);
                    }
                }
            }
            for (int i=0; i<nodes.size(); ++i) {
                for (int j=i+1; j < nodes.size(); ++j) {
                    Node u = nodes.get(i);
                    Node v = nodes.get(j);
                    Edge e = graph.getEdge(u, v);
                    e.getTweets().add(t);
                }
            }
            graph.addTweet(t);
        }
    }

}
